package com.jx.gocomtask.webservice.task;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.jx.gocomtask.webservice.DTO.CallMeStatus;
import com.jx.gocomtask.webservice.DTO.CycleRun;
import com.jx.gocomtask.webservice.DTO.StatusMessage;
import com.jx.gocomtask.webservice.DTO.TaskStatus;
import com.jx.gocomtask.webservice.entity.ExtRemindPlan;
import com.jx.gocomtask.webservice.entity.ExtTaskMessage;
import com.jx.gocomtask.webservice.entity.ExtTaskUser;
import com.jx.gocomtask.webservice.repository.ExtRemindPlanRepository;
import com.jx.gocomtask.webservice.repository.ExtTaskMessageRepository;
import com.jx.gocomtask.webservice.service.SendMessageService;
import com.jx.gocomtask.webservice.service.SystemSuperApp;

@Component("repeatPlan")  
public class RepeatPlan {
	private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(RepeatPlan.class);
	private final String method_single="message/single/send/status?";
	  @Autowired
	    RestTemplate restTemplate;
	  @Resource(name="apiurl")
		String gocomeApiUrl;
	  @Autowired
		SystemSuperApp systemSuperApp;
	  @Resource(name="defaultAppId")
		String defaultAppId;
	  @Resource(name="taskDetails")
		String taskDetails;
	  @Autowired
	  SendMessageService sendMessageService;
	@Autowired
	ExtTaskMessageRepository extTaskMessageRepository;
	@Autowired
	ExtRemindPlanRepository extRemindPlanRepository;
	@Scheduled(cron = "0 10 0 * * ?")  
	public void resetPaln(){
		List<ExtTaskMessage> extTaskMessages=extTaskMessageRepository.pRepeatSchedlue();
		List<ExtTaskMessage> extTaskMessage_repeats=new LinkedList<>();
		for(ExtTaskMessage em:extTaskMessages){
			ExtTaskMessage extTaskMessage=resetExtTaskMessagePaln(em);
			if(extTaskMessage!=null){
				extTaskMessage_repeats.add(extTaskMessage);
			}
		}
		if(extTaskMessage_repeats.size()>0)
			extTaskMessageRepository.save(extTaskMessage_repeats);
	}
	/*public void resetPaln(){
		LocalDate today = LocalDate.now();
		List<ExtTaskMessage> extTaskMessages=extTaskMessageRepository.pRepeatSchedlue();
		List<ExtTaskMessage> extTaskMessage_repeats=new LinkedList<>();
		for(ExtTaskMessage em:extTaskMessages){
			ExtTaskMessage extTaskMessage=null;
			Date date=em.getDeadline();
			Instant instant = date.toInstant();
			if(em.getIsRepeat()==CycleRun.DAY ){
				LocalDateTime deadline=LocalDateTime.now();
			    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
			    deadline=LocalDate.now().atTime(localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond());
			    extTaskMessage=resetOnePaln(em,deadline);
			}else if(em.getIsRepeat()==CycleRun.WEEK  && em.getIsRepeat()==CycleRun.WEEK && today.getDayOfWeek()==DayOfWeek.MONDAY){
				LocalDateTime todayTime=LocalDateTime.now();
				LocalDateTime deadline = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
				int monday= today.getDayOfWeek().getValue();
				int w=deadline.getDayOfWeek().getValue();
				long ws=w-monday;
				extTaskMessage=resetOnePaln(em,todayTime.plusDays(ws));
			}
			if(extTaskMessage!=null){
				extTaskMessage_repeats.add(extTaskMessage);
			}
		}
		if(extTaskMessage_repeats.size()>0)
			extTaskMessageRepository.save(extTaskMessage_repeats);
	}*/
	private ExtTaskMessage resetExtTaskMessagePaln(ExtTaskMessage em){
		LocalDate today = LocalDate.now();
		ExtTaskMessage extTaskMessage=null;
		Date date=em.getDeadline();
		Instant instant = date.toInstant();
		if(em.getIsRepeat()==CycleRun.DAY ){
			LocalDateTime deadline=LocalDateTime.now();
		    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
		    deadline=LocalDate.now().atTime(localDateTime.getHour(), localDateTime.getMinute(), localDateTime.getSecond());
		    extTaskMessage=resetOnePaln(em,deadline);
		}else if(em.getIsRepeat()==CycleRun.WEEK  && em.getIsRepeat()==CycleRun.WEEK && today.getDayOfWeek()==DayOfWeek.MONDAY){
			LocalDateTime todayTime=LocalDateTime.now();
			LocalDateTime deadline = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
			int monday= today.getDayOfWeek().getValue();
			int w=deadline.getDayOfWeek().getValue();
			long ws=w-monday;
			extTaskMessage=resetOnePaln(em,todayTime.plusDays(ws));
		}
		return extTaskMessage;
	}
	private ExtTaskUser converterExtTaskUser(ExtTaskUser e){
		ExtTaskUser extTaskUser_=new ExtTaskUser();
		BeanUtils.copyProperties(e,extTaskUser_);
		extTaskUser_.setId(null);
		extTaskUser_.setStatus(TaskStatus.START);
		return extTaskUser_;
	}
	
	private ExtTaskMessage resetOnePaln(ExtTaskMessage extTaskMessage,LocalDateTime deadline){
		ExtTaskMessage extTaskMessage_=new ExtTaskMessage();
		BeanUtils.copyProperties(extTaskMessage,extTaskMessage_);
		String uuid = UUID.randomUUID().toString();
		extTaskMessage_.setUuid(uuid);
		//extTaskMessage_.setpId(extTaskMessage.getId());
		extTaskMessage_.setIsRepeat(CycleRun.NO);
		extTaskMessage_.setId(null);
		extTaskMessage_.setDeadline(Date.from(deadline.atZone(ZoneId.systemDefault()).toInstant()));
		extTaskMessage_.setStatus(TaskStatus.START);
		extTaskMessage_.setExtTaskExtension(null);
		List<ExtTaskUser> extTaskUsers= extTaskMessage.getExtTaskUser();
		extTaskMessage_.getExtTaskUser().clear();
		extTaskMessage_.getExtTaskUser().addAll(extTaskUsers.stream().map(this::converterExtTaskUser).collect(Collectors.toList()));
		this.createRemindPlan(extTaskMessage_);
		return extTaskMessage_;
	}
	@Scheduled(cron = "0 0/5 * * * ?")  
	public void sendMessage(){
		LocalDateTime todayTime = LocalDateTime.now();
		LocalDateTime todayTime5=todayTime.plusMinutes(5);
		ZoneId zone = ZoneId.systemDefault();
		java.util.Date start = Date.from(todayTime.atZone(zone).toInstant());
		java.util.Date end = Date.from(todayTime5.atZone(zone).toInstant());
		List<ExtRemindPlan> extRemindPlans= extRemindPlanRepository.findByExecTimeBetween(start, end);
		extRemindPlans.forEach(this::sendOneMessage);
		extRemindPlanRepository.delete(extRemindPlans);
	}
	private void sendOneMessage(ExtRemindPlan extRemindPlan){
		ExtTaskMessage extTaskMessage=extRemindPlan.getExtTaskMessage();
		//CallMeStatus callMeStatus=extTaskMessage.getIsRemind();
		if(extTaskMessage.getStatus().ordinal()>=TaskStatus.OVER.ordinal()){
			return;
		}
		 String url=taskDetails+"&taskId="+extTaskMessage.getUuid();
		 //List<ExtTaskUser> extTaskUsers= extTaskMessage.getExtTaskUser();
		 extTaskMessage.getExtTaskUser().forEach(e->{
			 if(e.getStatus().ordinal()>=TaskStatus.FINISHED.ordinal()){
				 return;
			 }
			 StatusMessage statusMessage =tixing(e.getTaskUser(),url);
			sendMessageService.sendMessage(sendMessageService.sendUrl(gocomeApiUrl, defaultAppId, method_single), statusMessage);
		 });
	}
	public void createRemindPlan(ExtTaskMessage extTaskMessage){
		Date date=reminded(extTaskMessage);
		if(date!=null){
			ExtRemindPlan extRemindPlan=new ExtRemindPlan();
			extRemindPlan.setExtTaskMessage(extTaskMessage);
			extRemindPlan.setExecTime(date);
			extTaskMessage.setExtRemindPlan(extRemindPlan);
		}
	}
	public Date reminded(ExtTaskMessage extTaskMessage){
		CallMeStatus callMeStatus=extTaskMessage.getIsRemind();
		Instant instant = extTaskMessage.getDeadline().toInstant();
		ZoneId zone = ZoneId.systemDefault();
		LocalDateTime todayTime = LocalDateTime.now().plusMinutes(5L);
		 switch (callMeStatus) {
			 case QUARTER:
				 LocalDateTime localDateTime_15 = LocalDateTime.ofInstant(instant, zone);
				 localDateTime_15 =localDateTime_15.minusMinutes(15L);
				 if(localDateTime_15.isAfter(todayTime)){
					 return Date.from(localDateTime_15.atZone(zone).toInstant());
				 }
				 return null;
			 case HOUR:
				 LocalDateTime localDateTime_hour = LocalDateTime.ofInstant(instant, zone);
				 localDateTime_hour =localDateTime_hour.minusHours(1L);
				 if(localDateTime_hour.isAfter(todayTime)){
					 return Date.from(localDateTime_hour.atZone(zone).toInstant());
				 }
				 return null;
			 case THREEHOUR:
				 LocalDateTime localDateTime_3hour = LocalDateTime.ofInstant(instant, zone);
				 localDateTime_3hour =localDateTime_3hour.minusHours(3L);
				 if(localDateTime_3hour.isAfter(todayTime)){
					 return Date.from(localDateTime_3hour.atZone(zone).toInstant());
				 }
				 return null;
			default:
				return null;
		}
	}
	private StatusMessage tixing(String touser,String url){
		StatusMessage statusMessage = new StatusMessage();
		statusMessage.setTouser(touser);
		StatusMessage.Begin begin=new StatusMessage.Begin();
		StatusMessage.Content contentext=new StatusMessage.Content();
		List<StatusMessage.Form> forms=new ArrayList<>();
		contentext.setTitle("您有一个任务到期提醒");
		contentext.setDetail(" ");
		begin.setContent(contentext);
		begin.setUrl(url);
		begin.setIos(url);
		begin.setAndroid(url);
		statusMessage.setBegin(begin);
		return statusMessage;
	}
}
